home *** CD-ROM | disk | FTP | other *** search
/ Aminet 43 / Aminet 43 (2001)(GTI - Schatztruhe)[!][Jun 2001].iso / Aminet / dev / moni / SystemViewer.lha / Source / SysTasks.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-09-19  |  33.6 KB  |  1,390 lines

  1. /****h *AmigaTalk/SysTasks.c *****************************************
  2. **
  3. ** NAME
  4. **    SysTasks.c
  5. **
  6. ** DESCRIPTION
  7. **    Display a list of all tasks & processes currently loaded into
  8. **    the OS.  Allow the user to signal, break, & view almost all
  9. **    important parameters of the task or process.
  10. **
  11. ** FUNCTIONAL INTERFACE:
  12. **
  13. **    PUBLIC void RemovePortSafely( struct MsgPort *port );
  14. **
  15. **    PUBLIC int HandleTaskListView( void );
  16. **
  17. **  GUI Designed by : Jim Steichen
  18. **********************************************************************
  19. */
  20.  
  21. #include <stdio.h>
  22. #include <string.h>
  23.  
  24. #include <exec/execbase.h>
  25. #include <exec/types.h>
  26.  
  27. #include <dos/dosextens.h>
  28.  
  29. #include <AmigaDOSErrs.h>
  30.  
  31. #include <intuition/intuitionbase.h>
  32. #include <intuition/intuition.h>
  33. #include <intuition/classes.h>
  34. #include <intuition/classusr.h>
  35. #include <intuition/gadgetclass.h>
  36.  
  37. #include <libraries/gadtools.h>
  38.  
  39. #include <graphics/displayinfo.h>
  40. #include <graphics/gfxbase.h>
  41.  
  42. #include <clib/exec_protos.h>
  43. #include <clib/intuition_protos.h>
  44. #include <clib/gadtools_protos.h>
  45. #include <clib/graphics_protos.h>
  46. #include <clib/utility_protos.h>
  47. #include <clib/diskfont_protos.h>
  48.  
  49. #include "CPGM:GlobalObjects/CommonFuncs.h"
  50.  
  51. #include "SysLists.h"
  52.  
  53. #define XPOS       6
  54. #define MAX_HEIGHT 370
  55. #define MAXNODE    100
  56.  
  57. PRIVATE void WriteTask( void *ptr );
  58.  
  59. PRIVATE char ver[] = "$VER: SysTasks 1.0 (12/20/1999) by J.T. Steichen";
  60.  
  61. PRIVATE struct Window *IWnd = NULL;
  62.  
  63. PRIVATE UWORD ILeft   = 0;
  64. PRIVATE UWORD ITop    = 32;
  65. PRIVATE UWORD IWidth  = 640;
  66. PRIVATE UWORD IHeight = MAX_HEIGHT;
  67.  
  68. PRIVATE UBYTE *IWTitle = "System Tasks & Processes Full Info:";
  69.  
  70. PRIVATE struct Gadget *TaskGadgets[ T_CNT ];
  71.  
  72. PRIVATE UBYTE *WTitle = "System Tasks & Processes Info:";
  73.  
  74. // defined in SysLists.h:  PRIVATE struct Window *Wnd = NULL;
  75.  
  76. PRIVATE UWORD StrYPos[32] = { 0, };
  77.  
  78. PRIVATE struct MinList TskLVList;
  79.  
  80. PRIVATE struct Node TskLVNode;
  81. PRIVATE struct Node TskLVNodes[ MAXNODE ] = { NULL, };
  82.  
  83. PRIVATE UBYTE       NodeStrs[ MAXNODE * 80 ] = "";
  84.  
  85. PRIVATE UWORD TaskGTypes[] = {
  86.  
  87.    LISTVIEW_KIND, BUTTON_KIND,   BUTTON_KIND,
  88.    BUTTON_KIND,   BUTTON_KIND,   BUTTON_KIND,
  89.    BUTTON_KIND,   BUTTON_KIND,   BUTTON_KIND, TEXT_KIND
  90. };
  91.  
  92. PRIVATE int TLVClicked(      int itemnum );
  93. PRIVATE int UpdateClicked(   int dummy   );
  94. PRIVATE int RemoveClicked(   int dummy   );
  95. PRIVATE int PriorityClicked( int dummy   );
  96. PRIVATE int CancelClicked(   int dummy   );
  97. PRIVATE int FreezeClicked(   int dummy   );
  98. PRIVATE int MoreClicked(     int dummy   );
  99. PRIVATE int SignalClicked(   int dummy   );
  100. PRIVATE int BreakClicked(    int dummy   );
  101.  
  102. /* Since this is an array, the gadgets are in numerical order 
  103. ** (by GadgetID number).
  104. */
  105.  
  106. PRIVATE struct NewGadget TaskNGad[] = {
  107.  
  108.      2,   3, 627, 200,                 NULL, NULL, TaskLV, 
  109.    0,            NULL, (APTR) TLVClicked,
  110.    
  111.      4, 205,  71,  17, (UBYTE *) "_Update",  NULL, TUpdate, 
  112.    PLACETEXT_IN, NULL, (APTR) UpdateClicked,
  113.    
  114.     82, 205,  71,  17, (UBYTE *) "_More",    NULL, TMore, 
  115.    PLACETEXT_IN, NULL, (APTR) MoreClicked,
  116.    
  117.    554, 205,  72,  17, (UBYTE *) "_Cancel",  NULL, TCancel, 
  118.    PLACETEXT_IN, NULL, (APTR) CancelClicked,
  119.    
  120.    474, 205,  72,  17, (UBYTE *) "Freeze",   NULL, TFreeze, 
  121.    PLACETEXT_IN, NULL, (APTR) FreezeClicked,
  122.    
  123.    317, 205,  72,  17, (UBYTE *) "Remove",   NULL, TRemove, 
  124.    PLACETEXT_IN, NULL, (APTR) RemoveClicked,
  125.    
  126.    160, 205,  72,  17, (UBYTE *) "Signal",   NULL, TSignal, 
  127.    PLACETEXT_IN, NULL, (APTR) SignalClicked,
  128.    
  129.    238, 205,  72,  17, (UBYTE *) "_Break",   NULL, TBreak, 
  130.    PLACETEXT_IN, NULL, (APTR) BreakClicked,
  131.       
  132.    396, 205,  72,  17, (UBYTE *) "Priority", NULL, TPriority, 
  133.    PLACETEXT_IN, NULL, (APTR) PriorityClicked,
  134.    
  135.      5, 228, 620,  17,                 NULL, NULL, TSelection,
  136.               0, NULL, NULL
  137. };
  138.  
  139. PRIVATE ULONG TaskGTags[] = {
  140.  
  141.    GTLV_ShowSelected, NULL, (LAYOUTA_Spacing), 2, (TAG_DONE),
  142.  
  143.    (GT_Underscore), '_', (TAG_DONE),
  144.    (GT_Underscore), '_', (GA_Disabled), TRUE, (TAG_DONE),
  145.    (GT_Underscore), '_', (TAG_DONE),
  146.  
  147.    (GA_Disabled),  TRUE, (TAG_DONE),
  148.    (GA_Disabled),  TRUE, (TAG_DONE),
  149.    (GA_Disabled),  TRUE, (TAG_DONE),
  150.  
  151.    (GT_Underscore), '_', (GA_Disabled), TRUE, (TAG_DONE),
  152.  
  153.    (GA_Disabled),  TRUE, (TAG_DONE),
  154.  
  155.    (GTTX_Border),  TRUE, TAG_DONE
  156. };
  157.  
  158. // --------------------------------------------------------------------
  159.  
  160. PRIVATE void WriteText( char *string, int xpos, int ypos, int color ) 
  161. {
  162.    struct RastPort  *rp = IWnd->RPort;
  163.    struct IntuiText  outtxt;
  164.  
  165.    outtxt.FrontPen  = color;
  166.    outtxt.BackPen   = 0;
  167.    outtxt.DrawMode  = JAM1;
  168.    outtxt.LeftEdge  = 0;
  169.    outtxt.TopEdge   = 0;
  170.    outtxt.ITextFont = Font;
  171.    outtxt.NextText  = NULL;
  172.    outtxt.IText     = (UBYTE *) string;
  173.  
  174.    PrintIText( rp, &outtxt, xpos, ypos );
  175.  
  176.    return;
  177. }
  178.  
  179.  
  180. PRIVATE BOOL CheckWindow( struct Window *findwin )
  181. {
  182.   struct Window *win;
  183.   struct Screen *scr;
  184.   ULONG          lock = 0L;
  185.   BOOL           ret  = FALSE;
  186.  
  187.   lock = LockIBase( NULL );
  188.  
  189.   scr = IntuitionBase->FirstScreen;
  190.   
  191.   while ((scr != NULL) && (ret == FALSE))
  192.      {
  193.      win = scr->FirstWindow;
  194.      
  195.      while (win != NULL)
  196.         {
  197.         if (win == findwin)
  198.            {
  199.            ret = TRUE;
  200.            break;
  201.            }
  202.  
  203.         win = win->NextWindow;
  204.         }
  205.  
  206.      scr = scr->NextScreen;
  207.      }
  208.  
  209.   UnlockIBase( lock );
  210.  
  211.   return( ret );
  212. }
  213.  
  214. PRIVATE void CloseIWindow( void )
  215. {
  216.    if (IWnd != NULL) 
  217.       {
  218.       CloseWindow( IWnd );
  219.       IWnd = NULL;
  220.       }
  221.  
  222.    return;
  223. }
  224.  
  225. PRIVATE int ICloseWindow( void )
  226. {
  227.    CloseIWindow();
  228.    return( (int) FALSE );
  229. }
  230.  
  231. PRIVATE BOOL CheckBit( int flags, int bit )
  232. {
  233.    if ((flags & bit) == bit)
  234.       return( TRUE );
  235.    else
  236.       return( FALSE );
  237. }
  238.  
  239. PRIVATE void DisplayStructure( void *ptr, int struct_type )
  240. {
  241.    switch (struct_type)
  242.       {
  243.       case 2: // Task structure:
  244.          WriteTask( ptr );
  245.          break;
  246.  
  247.       case 3: // Process structure:
  248.          WriteTask( ptr );
  249.          break;
  250.       }
  251.  
  252.    return;
  253. }
  254.  
  255. PRIVATE int OpenIWindow( int numlines )
  256. {
  257.    UWORD wleft = ILeft, wtop = ITop, ww, wh;
  258.    int   i;
  259.    
  260.    ComputeFont( Scr, Font, &CFont, IWidth, IHeight );
  261.  
  262.    IHeight = (numlines + 1) * (CFont.FontY + 3) + 2;
  263.  
  264.    if (IHeight > MAX_HEIGHT)
  265.       IHeight = MAX_HEIGHT;
  266.  
  267.    for (i = 0; i < 32; i++)
  268.       StrYPos[i] = 16 + i * (CFont.FontY + 3);
  269.          
  270.    ww = ComputeX( CFont.FontX, IWidth  );
  271.    wh = ComputeY( CFont.FontY, IHeight );
  272.  
  273.    if ((wleft + ww + CFont.OffX + Scr->WBorRight) > Scr->Width) 
  274.       wleft = Scr->Width - ww;
  275.  
  276.    if ((wtop + wh + CFont.OffY + Scr->WBorBottom) > Scr->Height) 
  277.       wtop = Scr->Height - wh;
  278.  
  279.    if ( !(IWnd = OpenWindowTags( NULL,
  280.  
  281.                    WA_Left,        wleft,
  282.                    WA_Top,         wtop,
  283.                    WA_Width,       ww + CFont.OffX + Scr->WBorRight,
  284.                    WA_Height,      wh + CFont.OffY + Scr->WBorBottom,
  285.  
  286.                    WA_IDCMP,       BUTTONIDCMP | IDCMP_GADGETUP
  287.                      | IDCMP_REFRESHWINDOW | IDCMP_CLOSEWINDOW,
  288.  
  289.                    WA_Flags,       WFLG_SMART_REFRESH | WFLG_CLOSEGADGET 
  290.                      | WFLG_ACTIVATE | WFLG_RMBTRAP,
  291.  
  292.                    WA_Gadgets,     NULL,
  293.                    WA_Title,       IWTitle,
  294.                    WA_ScreenTitle, ScrTitle,
  295.                    TAG_DONE ))
  296.       )
  297.       return( -4 );
  298.  
  299.    return( 0 );
  300. }
  301.  
  302. PRIVATE int HandleInfoIDCMP( void )
  303. {
  304.    struct IntuiMessage    *m;
  305.    BOOL            running = TRUE;
  306.  
  307.    while (running == TRUE)
  308.       {
  309.       if ((m = (struct IntuiMessag *) GetMsg( IWnd->UserPort )) == NULL)
  310.          {
  311.          (void) Wait( 1L << IWnd->UserPort->mp_SigBit );
  312.          continue;
  313.          }
  314.  
  315.       CopyMem( (char *) m, (char *) &IMsg, 
  316.                (long) sizeof( struct IntuiMessage )
  317.              );
  318.  
  319.       ReplyMsg( (struct Message *) m );
  320.  
  321.       switch (IMsg.Class) 
  322.          {
  323.         case IDCMP_CLOSEWINDOW:
  324.            running = ICloseWindow();
  325.             break;
  326.          }
  327.       }
  328.  
  329.    return( running );
  330. }
  331.  
  332. PUBLIC int HandleWindowInfo( void *structptr, int whichdisplay )
  333. {
  334.    int rval = 0;
  335.    
  336.    switch (whichdisplay)
  337.       {
  338.       case 2: // Task data:
  339.          rval = OpenIWindow( 13 );
  340.          break;
  341.  
  342.       case 3: // Process data:
  343.          rval = OpenIWindow( 28 );
  344.          break;
  345.       }
  346.    
  347.    if (rval < 0)
  348.       {
  349.       (void) Handle_Problem( "Couldn't open Information Window!", 
  350.                              "Allocation Problem:", NULL 
  351.                            );
  352.       return( -1 );
  353.       }
  354.  
  355.    DisplayStructure( structptr, whichdisplay );
  356.       
  357.    (void) HandleInfoIDCMP();
  358.  
  359.    return( 0 );
  360. }
  361.  
  362. PRIVATE char ts[10], *taskstate = &ts[0];
  363. PRIVATE BOOL DispTaskFlag = TRUE;
  364.  
  365. PRIVATE char *GetTaskState( struct Task *t )
  366. {
  367.    if (t == NULL)
  368.       return( "INVALID" );
  369.  
  370.    switch (t->tc_State)
  371.       {
  372.       case TS_INVALID:
  373.          strcpy( taskstate, "INVALID" );  // Stack won't be right.
  374.          DispTaskFlag = FALSE;
  375.          break;
  376.          
  377.       case TS_ADDED:
  378.          strcpy( taskstate, "ADDED" );
  379.          DispTaskFlag = TRUE;
  380.          break;
  381.          
  382.       case TS_RUN:
  383.          strcpy( taskstate, "RUNNING" );
  384.          DispTaskFlag = TRUE;
  385.          break;
  386.          
  387.       case TS_READY:
  388.          strcpy( taskstate, "READY" );
  389.          DispTaskFlag = TRUE;
  390.          break;
  391.          
  392.       case TS_WAIT:
  393.          strcpy( taskstate, "WAITING" );
  394.          DispTaskFlag = TRUE;
  395.          break;
  396.          
  397.       case TS_EXCEPT:
  398.          strcpy( taskstate, "EXCEPTION" );
  399.          DispTaskFlag = TRUE;
  400.          break;
  401.          
  402.       case TS_REMOVED:
  403.          strcpy( taskstate, "REMOVED" );
  404.          DispTaskFlag = TRUE;
  405.          break;
  406.       }
  407.  
  408.    return( taskstate );
  409. }
  410.  
  411. PRIVATE void SetTaskFlags( struct Task *t, char *str )
  412. {
  413.    *str = '\0';
  414.  
  415.    if (CheckBit( t->tc_Flags, TF_PROCTIME ) == TRUE)
  416.       strcpy( str, "TF_PROCTIME " );
  417.    
  418.    if (CheckBit( t->tc_Flags, TF_ETASK ) == TRUE)
  419.       strcat( str, "TF_ETASK " );
  420.  
  421.    if (CheckBit( t->tc_Flags, TF_STACKCHK ) == TRUE)
  422.       strcat( str, "TF_STACKCHK " );
  423.  
  424.    if (CheckBit( t->tc_Flags, TF_EXCEPT ) == TRUE)
  425.       strcat( str, "TF_EXCEPT " );
  426.  
  427.    if (CheckBit( t->tc_Flags, TF_SWITCH ) == TRUE)
  428.       strcat( str, "TF_SWITCH " );
  429.  
  430.    if (CheckBit( t->tc_Flags, TF_LAUNCH ) == TRUE)
  431.       strcat( str, "TF_LAUNCH" );
  432.  
  433.    return;
  434. }
  435.  
  436. PRIVATE char typ[10], *pgmtype = &typ[0];
  437.  
  438. PRIVATE char *GetTask_Process( UBYTE type )
  439. {
  440.    if (type == NT_TASK)
  441.       strcpy( pgmtype, "TASK" );
  442.    else if (type == NT_PROCESS)
  443.       strcpy( pgmtype, "PROCESS" );
  444.    else   
  445.       strcpy( pgmtype, "TASK" );
  446.  
  447.    return( pgmtype );
  448. }
  449.  
  450. #define B2APTR( bptr ) ((bptr) << 2)
  451.  
  452. #define XPOS 6
  453.  
  454. PRIVATE void WriteTask( void *ptr )
  455. {
  456.    IMPORT UWORD StrYPos[];
  457.    
  458.    struct Task    *task    = (struct Task *) ptr;
  459.    struct Process *process = NULL;
  460.  
  461.    char t[82], *title = &t[0];
  462.    char s[82], *str   = &s[0];
  463.  
  464.    int  size = 0;
  465.    
  466.    if (task == NULL)
  467.       return; 
  468.  
  469.    sprintf( title, "%10.10s: (%08LX) -> %-32.32s", 
  470.             GetTask_Process( task->tc_Node.ln_Type ),
  471.             task, task->tc_Node.ln_Name
  472.           );
  473.  
  474.    SetWindowTitles( Wnd, title, (UBYTE *) 0xFFFFFFFF );
  475.  
  476.    // Common (to Task & Process) data to display:
  477.    if ((task->tc_Node.ln_Type == NT_TASK) 
  478.        || (task->tc_Node.ln_Type == NT_PROCESS))
  479.       {
  480.       sprintf( str, "STATE: %s Priority: %4d", 
  481.                GetTaskState( task ),
  482.                task->tc_Node.ln_Pri 
  483.              );
  484.  
  485.       WriteText( str, XPOS, StrYPos[0], 2 );
  486.  
  487.       sprintf( str, "SigAlloc: %08LX SigWait : %08LX SigRecvd : %08LX SigExcept: %08LX", 
  488.                task->tc_SigAlloc, task->tc_SigWait, 
  489.                task->tc_SigRecvd, task->tc_SigExcept
  490.              );
  491.  
  492.       WriteText( str, XPOS, StrYPos[1], 1 );
  493.  
  494.       sprintf( str, "TrapData: %08LX TrapCode: %08LX TrapAlloc: %08LX TrapAble : %08LX",
  495.                task->tc_TrapData, task->tc_TrapCode, 
  496.                task->tc_TrapAlloc, task->tc_TrapAble
  497.              );
  498.  
  499.       WriteText( str, XPOS, StrYPos[2], 1 );
  500.  
  501.       sprintf( str, "Switch(): %08LX Launch(): %08LX UserData : %08LX", 
  502.                task->tc_Switch, task->tc_Launch, 
  503.                task->tc_UserData
  504.              );
  505.  
  506.       WriteText( str, XPOS, StrYPos[3], 2 );
  507.  
  508.       sprintf( str, "ExceptData: %08LX ExceptCode: %08LX", 
  509.                task->tc_ExceptData, task->tc_ExceptCode
  510.              );
  511.  
  512.       WriteText( str, XPOS, StrYPos[5], 1 );
  513.  
  514.       size = (int) task->tc_SPUpper - (int) task->tc_SPLower;
  515.  
  516.       sprintf( str, "SPReg     : %08LX SPUpper   : %08LX SPLower: %08LX size: %d",
  517.                task->tc_SPReg, task->tc_SPUpper, 
  518.                task->tc_SPLower, size
  519.              );
  520.  
  521.       WriteText( str, XPOS, StrYPos[6], 2 );
  522.  
  523.       sprintf( str, "IDNestCnt: %-08d TDNestCnt: %3d",
  524.                task->tc_IDNestCnt, task->tc_TDNestCnt
  525.              );
  526.  
  527.       WriteText( str, XPOS, StrYPos[8], 1 );
  528.  
  529.       sprintf( str, "MemEntry : %08LX", task->tc_MemEntry.lh_Head );
  530.  
  531.       WriteText( str, XPOS, StrYPos[9], 1 );
  532.  
  533.       WriteText( "Flags:", XPOS, StrYPos[10], 3 );
  534.  
  535.       SetTaskFlags( task, str );
  536.  
  537.       WriteText( str, XPOS, StrYPos[11], 1 );
  538.  
  539.       if (task->tc_Node.ln_Type == NT_TASK) 
  540.          WriteText( "Press Close Gadget when you're done!", 
  541.                     150, StrYPos[12], 2 
  542.                   ); 
  543.       }
  544.  
  545.    // Process additions to display:
  546.    if (task->tc_Node.ln_Type == NT_PROCESS)
  547.       {
  548.       char   pn[256], *path = &pn[0];
  549.       UBYTE *ttl = NULL;
  550.             
  551.       process = (struct Process *) ptr;
  552.  
  553.       WriteText( "Process Structure:", XPOS, StrYPos[12], 3 );  
  554.  
  555.       if ((struct Window *) process->pr_WindowPtr != NULL)
  556.          ttl = ((struct Window *) process->pr_WindowPtr)->Title;
  557.       else
  558.          ttl = "*NO TITLE!*";
  559.  
  560.       sprintf( str, "WindowPtr  : %08LX Title: %-40.40s", 
  561.                process->pr_WindowPtr, 
  562.                (strlen( ttl ) > 0) ? ttl : (UBYTE *) "*NO TITLE!*"
  563.              );
  564.  
  565.       WriteText( str, XPOS, StrYPos[13], 2 );
  566.  
  567.       if (process->pr_CurrentDir != NULL)
  568.          (void) NameFromLock( process->pr_CurrentDir, path, 255 );
  569.           
  570.       sprintf( str, "CurrentDir : %08LX Path : %-40.40s", 
  571.                B2APTR( process->pr_CurrentDir ),
  572.                (path == NULL) ? "*NO PATH*" : path
  573.              );
  574.  
  575.       WriteText( str, XPOS, StrYPos[14], 2 );
  576.  
  577.       sprintf( str, "MsgPort    : %08LX SegList       : %08LX", 
  578.                process->pr_MsgPort, B2APTR( process->pr_SegList )
  579.              );
  580.  
  581.       WriteText( str, XPOS, StrYPos[15], 1 );
  582.  
  583.       sprintf( str, "StackBase  : %08LX StackSize     : %d", 
  584.                B2APTR( process->pr_StackBase ), process->pr_StackSize
  585.              );
  586.  
  587.       WriteText( str, XPOS, StrYPos[16], 1 );
  588.  
  589.       sprintf( str, "CIS        : %08LX COS           : %08LX", 
  590.                B2APTR( process->pr_CIS ), B2APTR( process->pr_COS )
  591.              );
  592.  
  593.       WriteText( str, XPOS, StrYPos[17], 1 );
  594.  
  595.       sprintf( str, "ConsoleTask: %08LX FileSystemTask: %08LX", 
  596.                process->pr_ConsoleTask, 
  597.                process->pr_FileSystemTask
  598.              );
  599.  
  600.       WriteText( str, XPOS, StrYPos[18], 1 );
  601.  
  602.       sprintf( str, "PktWait    : %08LX ReturnAddr    : %08LX", 
  603.                process->pr_PktWait, 
  604.                process->pr_ReturnAddr
  605.              );
  606.  
  607.       WriteText( str, XPOS, StrYPos[19], 1 );
  608.  
  609.       sprintf( str, "Arguments -> %-60.60s", 
  610.                (process->pr_Arguments == NULL) ? (UBYTE *) "*NO ARGS!*" 
  611.                                                : process->pr_Arguments
  612.              );
  613.  
  614.       WriteText( str, XPOS, StrYPos[20], 2 );
  615.  
  616.       sprintf( str, "GlobVec    : %08LX CLI           : %08LX", 
  617.                process->pr_GlobVec, 
  618.                B2APTR( process->pr_CLI )
  619.              );
  620.  
  621.       WriteText( str, XPOS, StrYPos[21], 1 );
  622.  
  623.       // CLI additional information: 
  624.  
  625.       if (process->pr_CLI != NULL)
  626.          {
  627.          struct CommandLineInterface *cli = NULL;
  628.          BOOL                         iflag = FALSE, bflag = FALSE;
  629.  
  630.          cli = (struct CommandLineInterface *) (process->pr_CLI << 2);
  631.  
  632.          WriteText( "CommandLineInterface structure:", 
  633.                     XPOS, StrYPos[22], 3
  634.                   );
  635.  
  636.          sprintf( str, "CommandDir   : %08LX", 
  637.                   B2APTR( cli->cli_CommandDir )
  638.                 );
  639.  
  640.          WriteText( str, XPOS, StrYPos[23], 1 );
  641.  
  642.          sprintf( str, "StandardInput: %08LX StandardOutput: %08LX", 
  643.                   B2APTR( cli->cli_StandardInput ),
  644.                   B2APTR( cli->cli_StandardOutput )
  645.                 );
  646.  
  647.          WriteText( str, XPOS, StrYPos[24], 1 );
  648.  
  649.          sprintf( str, "CurrentInput : %08LX CurrentOutput : %08LX", 
  650.                   B2APTR( cli->cli_CurrentInput  ),
  651.                   B2APTR( cli->cli_CurrentOutput )
  652.                 );
  653.  
  654.          WriteText( str, XPOS, StrYPos[25], 1 );
  655.  
  656.          if (cli->cli_Interactive != FALSE)
  657.             iflag = TRUE;
  658.             
  659.          if (cli->cli_Background != FALSE)
  660.             bflag = TRUE;
  661.             
  662.          sprintf( str, "Module       : %08LX %s %s", 
  663.                   B2APTR( cli->cli_Module ),
  664.                   (bflag == TRUE) ? "BACKGROUND" : "",
  665.                   (iflag == TRUE) ? "& INTERACTIVE" : ""
  666.                 );
  667.  
  668.          WriteText( str, XPOS, StrYPos[26], 1 );
  669.          }
  670.  
  671.       WriteText( "Press Close Gadget when you're done!", 
  672.                  150, StrYPos[27], 2 
  673.                ); 
  674.       }
  675.  
  676.    return;
  677. }
  678.  
  679. PRIVATE int MakeTaskList( void )
  680. {
  681.    IMPORT struct ExecBase *SysBase;
  682.    
  683.    struct Task *readytasks = NULL;
  684.    struct Task *waitgtasks = NULL;
  685.    struct Task *crnttask   = NULL;
  686.    struct Node *ptr        = NULL;
  687.  
  688.    char        *tskstate = NULL;
  689.    int          numitems = 0, i = 1;
  690.    int          up, down;
  691.         
  692.  
  693.    Forbid();
  694.  
  695.      crnttask = SysBase->ThisTask;
  696.  
  697.      up   = (int) crnttask->tc_SPUpper;
  698.      down = (int) crnttask->tc_SPLower;
  699.  
  700.      sprintf( &NodeStrs[ i++ * 80 ], 
  701.               "%08LX+ %4d %6u %08LX %-9.9s %-7.7s %-30.30s",
  702.               crnttask, 
  703.               crnttask->tc_Node.ln_Pri, 
  704.               up - down,
  705.               crnttask->tc_SigAlloc,
  706.               GetTaskState( crnttask ),
  707.               GetTask_Process( crnttask->tc_Node.ln_Type ),
  708.               crnttask->tc_Node.ln_Name
  709.             );
  710.      
  711.      numitems++;
  712.  
  713.      ptr        = SysBase->TaskReady.lh_Head;
  714.      readytasks = (struct Task *) ptr;
  715.  
  716.      while (ptr != NULL)
  717.         {
  718.         up   = (int) readytasks->tc_SPUpper;
  719.         down = (int) readytasks->tc_SPLower;
  720.  
  721.         tskstate = GetTaskState( readytasks );
  722.  
  723.         if (DispTaskFlag == TRUE)
  724.            sprintf( &NodeStrs[ i++ * 80 ], 
  725.                     "%08LX  %4d %6u %08LX %-9.9s %-7.7s %-30.30s",
  726.                     readytasks, 
  727.                     readytasks->tc_Node.ln_Pri, 
  728.                     up - down,
  729.                     readytasks->tc_SigAlloc,
  730.                     tskstate,
  731.                     GetTask_Process( readytasks->tc_Node.ln_Type ),
  732.                     readytasks->tc_Node.ln_Name
  733.                   );
  734.              
  735.         // point to next node in list:
  736.         ptr        = ptr->ln_Succ;
  737.         readytasks = (struct Task *) ptr;
  738.         numitems++;
  739.         }
  740.  
  741.      ptr        = SysBase->TaskWait.lh_Head;
  742.      waitgtasks = (struct Task *) ptr;
  743.  
  744.      while (ptr != NULL)
  745.         {
  746.         up   = (int) waitgtasks->tc_SPUpper;
  747.         down = (int) waitgtasks->tc_SPLower;
  748.  
  749.         tskstate = GetTaskState( waitgtasks );
  750.  
  751.         if (DispTaskFlag == TRUE)
  752.            sprintf( &NodeStrs[ i++ * 80 ], 
  753.                     "%08LX  %4d %6u %08LX %-9.9s %-7.7s %-30.30s",
  754.                     waitgtasks, 
  755.                     waitgtasks->tc_Node.ln_Pri, 
  756.                     up - down,
  757.                     waitgtasks->tc_SigAlloc,
  758.                     GetTaskState( waitgtasks ),
  759.                     GetTask_Process( waitgtasks->tc_Node.ln_Type ),
  760.                     waitgtasks->tc_Node.ln_Name
  761.                   );
  762.              
  763.         // point to next node in list:
  764.         ptr        = ptr->ln_Succ;
  765.         waitgtasks = (struct Task *) ptr;
  766.  
  767.         numitems++;
  768.         }
  769.  
  770.    Permit();
  771.  
  772.    return( numitems );
  773. }
  774.  
  775. PRIVATE ULONG TaskAddress = 0L;
  776.  
  777. PRIVATE int TLVClicked( int itemnum )
  778. {
  779.    ULONG addr = 0L;
  780.    
  781. //#  ifdef DEBUG
  782. //   fprintf( stderr, "%-80.80s\n", TskLVNodes[ itemnum ].ln_Name );
  783. //#  endif
  784.  
  785.    if (itemnum == 0)   
  786.       {
  787.       GT_SetGadgetAttrs( TaskGadgets[ TMore ], Wnd, NULL,
  788.                          GA_Disabled, TRUE, TAG_DONE 
  789.                        );
  790.  
  791.       GT_SetGadgetAttrs( TaskGadgets[ TFreeze ], Wnd, NULL,
  792.                          GA_Disabled, TRUE, TAG_DONE 
  793.                        );
  794.  
  795.       GT_SetGadgetAttrs( TaskGadgets[ TRemove ], Wnd, NULL,
  796.                          GA_Disabled, TRUE, TAG_DONE 
  797.                        );
  798.  
  799.       GT_SetGadgetAttrs( TaskGadgets[ TSignal ], Wnd, NULL,
  800.                          GA_Disabled, TRUE, TAG_DONE 
  801.                        );
  802.  
  803.       GT_SetGadgetAttrs( TaskGadgets[ TBreak ], Wnd, NULL,
  804.                          GA_Disabled, TRUE, TAG_DONE 
  805.                        );
  806.  
  807.       GT_SetGadgetAttrs( TaskGadgets[ TPriority ], Wnd, NULL,
  808.                          GA_Disabled, TRUE, TAG_DONE 
  809.                        );
  810.  
  811.       GT_SetGadgetAttrs( TaskGadgets[ TSelection ], Wnd, NULL,
  812.                          GTTX_Text, NULL,
  813.                          TAG_DONE
  814.                        );
  815.  
  816.       return( (int) TRUE );
  817.       }
  818.    else
  819.       {
  820.       GT_SetGadgetAttrs( TaskGadgets[ TMore ], Wnd, NULL,
  821.                          GA_Disabled, FALSE, TAG_DONE 
  822.                        );
  823.  
  824.       GT_SetGadgetAttrs( TaskGadgets[ TFreeze ], Wnd, NULL,
  825.                          GA_Disabled, FALSE, TAG_DONE 
  826.                        );
  827.  
  828.       GT_SetGadgetAttrs( TaskGadgets[ TRemove ], Wnd, NULL,
  829.                          GA_Disabled, FALSE, TAG_DONE 
  830.                        );
  831.  
  832.       GT_SetGadgetAttrs( TaskGadgets[ TSignal ], Wnd, NULL,
  833.                          GA_Disabled, FALSE, TAG_DONE 
  834.                        );
  835.  
  836.       GT_SetGadgetAttrs( TaskGadgets[ TBreak ], Wnd, NULL,
  837.                          GA_Disabled, FALSE, TAG_DONE 
  838.                        );
  839.  
  840.       GT_SetGadgetAttrs( TaskGadgets[ TPriority ], Wnd, NULL,
  841.                          GA_Disabled, FALSE, TAG_DONE 
  842.                        );
  843.  
  844.       GT_SetGadgetAttrs( TaskGadgets[ TSelection ], Wnd, NULL,
  845.                          GTTX_Text, TskLVNodes[ itemnum ].ln_Name, 
  846.                          TAG_DONE
  847.                        );
  848.  
  849.       // Now get address from the item:
  850.       (void) stch_l( TskLVNodes[ itemnum ].ln_Name, (long *) &addr );
  851.  
  852.       TaskAddress = addr;
  853.       }
  854.  
  855.    return( (int) TRUE );
  856. }
  857.  
  858. PRIVATE int UpdateClicked( int dummy )
  859. {
  860.    int i;
  861.    
  862.    GT_SetGadgetAttrs( TaskGadgets[ TSelection ], Wnd, NULL,
  863.                       GTTX_Text, NULL,
  864.                       TAG_DONE
  865.                     );
  866.  
  867.    for (i = 1; i <= MAXNODE; i++)
  868.        NodeStrs[ i * 80 ] = '\0'; // Kill old ListView strings.
  869.  
  870.    // Make the list:
  871.    (void) MakeTaskList();
  872.  
  873.    GT_RefreshWindow( Wnd, NULL );
  874.  
  875.    return( (int) TRUE );
  876. }
  877.  
  878. PRIVATE struct Window *FindTaskWindow( struct Task *task )
  879. {
  880.    struct Window *win, *taskwindow = NULL;
  881.    struct Screen *scr;
  882.    ULONG          lock = 0L;
  883.  
  884.    lock = LockIBase( NULL );
  885.  
  886.    scr = IntuitionBase->FirstScreen;
  887.    while ((scr != NULL) && (taskwindow == NULL))
  888.       {
  889.       win = scr->FirstWindow;
  890.      
  891.       while (win != NULL)
  892.          {
  893.          if ((win->UserPort != NULL) 
  894.               && (win->UserPort->mp_SigTask == task))
  895.             {
  896.             taskwindow = win;
  897.             break;
  898.             }
  899.  
  900.          win = win->NextWindow;
  901.          }
  902.  
  903.       scr = scr->NextScreen;
  904.       }
  905.  
  906.    UnlockIBase( lock );
  907.  
  908.    return( taskwindow );
  909. }
  910.  
  911. PUBLIC BOOL IsMsgPort_Empty( struct MsgPort *p )
  912. {
  913.    BOOL rval = FALSE;
  914.  
  915.    if (p == NULL)
  916.       return( TRUE );
  917.  
  918.    if (p->mp_MsgList.lh_TailPred == (struct Node *) &(p->mp_MsgList))
  919.       rval = TRUE;
  920.    
  921.    return( rval );
  922. }
  923.      
  924. PUBLIC void RemovePortSafely( struct MsgPort *port )
  925. {
  926.    struct Node *MsgNode;
  927.  
  928.    if (port == NULL)
  929.       return;
  930.  
  931.    Forbid();
  932.  
  933.      if (IsMsgPort_Empty( port ) == FALSE)
  934.         {
  935.         MsgNode = port->mp_MsgList.lh_Head;
  936.  
  937.         while ((MsgNode = MsgNode->ln_Succ) != NULL)
  938.            Remove( (struct Node *) MsgNode );
  939.         }
  940.  
  941.      if (port->mp_Node.ln_Name != NULL)
  942.         RemPort( port );
  943.  
  944.      port->mp_SigTask         = (struct Task *) -1;
  945.      port->mp_MsgList.lh_Head = (struct Node *) -1;
  946.  
  947.      DeletePort( port );
  948.  
  949.   Permit();
  950.  
  951.   return;
  952. }
  953.  
  954. PRIVATE void CloseTheWindow( struct Window *wind )
  955. {
  956.    if (CheckWindow( wind ) == TRUE)
  957.       {
  958.       if ((wind->ReqCount != 0) && wind->FirstRequest)
  959.          {
  960.          while (wind->ReqCount != 0)
  961.             EndRequest( wind->FirstRequest, wind );
  962.          }
  963.  
  964.       if (wind->DMRequest != NULL)
  965.          ClearDMRequest( wind );
  966.  
  967.       if (wind->Pointer != NULL)
  968.          ClearPointer( wind );
  969.  
  970.       if (wind->MenuStrip != NULL)
  971.          ClearMenuStrip( wind );
  972.  
  973.       CloseWindow( wind );
  974.       }
  975.  
  976.    return;
  977. }
  978.  
  979. PRIVATE struct Window *TaskWindow( struct Task *task )
  980. {
  981.    return( FindTaskWindow( task ) );
  982.  
  983. /* struct Window *rval = NULL;
  984.  
  985.    Forbid();
  986.  
  987.       if (task->tc_Node.ln_Type == NT_PROCESS)
  988.          {
  989.          struct Process *process = (struct Process *) task;
  990.  
  991.          if ((struct Window *) process->pr_WindowPtr != NULL)
  992.             rval = ((struct Window *) process->pr_WindowPtr);
  993.          }
  994.  
  995.    Permit();
  996.  
  997.    return( rval );
  998. */
  999. }
  1000.  
  1001. PRIVATE struct MsgPort *TaskPort( struct Task *task )
  1002. {
  1003.    struct MsgPort *rval = NULL;
  1004.    
  1005.    Forbid();
  1006.  
  1007.       if (task->tc_Node.ln_Type == NT_PROCESS)
  1008.          {
  1009.          struct Process *process = (struct Process *) task;
  1010.  
  1011.          rval = &(process->pr_MsgPort);
  1012.          }
  1013.    
  1014.    Permit();
  1015.  
  1016.    return( rval );
  1017. }
  1018.  
  1019. PRIVATE void KillTask( struct Task *task )
  1020. {
  1021.    struct Window  *taskwin = NULL;
  1022.    struct MsgPort *port    = NULL;
  1023.  
  1024.    Forbid();
  1025.      Disable();
  1026.        Remove( (struct Node *) task );
  1027.      Enable();
  1028.  
  1029.      if ((taskwin = TaskWindow( task )) != NULL)
  1030.         {
  1031.         struct Screen *taskscr = NULL;
  1032.         ULONG          lock    = LockIBase( NULL );
  1033.  
  1034.         if ((taskwin->WScreen != NULL) 
  1035.            && ((taskwin->WScreen->Flags & CUSTOMSCREEN) == CUSTOMSCREEN))
  1036.            taskscr = taskwin->WScreen;
  1037.  
  1038.         while (taskwin != NULL)
  1039.            {
  1040.            CloseTheWindow( taskwin );
  1041.            taskwin = TaskWindow( task );
  1042.            }
  1043.  
  1044.         if (taskscr != NULL)
  1045.            CloseScreen( taskscr );
  1046.   
  1047.         UnlockIBase (lock);
  1048.         }
  1049.  
  1050.      while (port = TaskPort( task ) != NULL)
  1051.         RemovePortSafely( port );
  1052.  
  1053.      Disable();
  1054.        RemTask( task );
  1055.      Enable();
  1056.  
  1057.    Permit();
  1058.  
  1059.    return;
  1060. }
  1061.  
  1062. PRIVATE int RemoveClicked( int dummy )
  1063. {
  1064.    char  m[80], *msg = &m[0];
  1065.    int   answer = -1;
  1066.    
  1067.    sprintf( msg, "Are you SURE you want to Remove %08x?", TaskAddress );
  1068.  
  1069.    answer = SanityCheck( msg );
  1070.  
  1071.    if (answer >= 0)
  1072.       KillTask( (struct Task *) TaskAddress );  // Send the remove command:
  1073.  
  1074.    return( (int) TRUE );
  1075. }
  1076.  
  1077. PRIVATE int PriorityClicked( int dummy )
  1078. {
  1079.    char m[80], *msg = &m[0];
  1080.    int  answer = -1;
  1081.    
  1082.    sprintf( msg, "Are you SURE you want to Re-Prioritize %08x?", 
  1083.             TaskAddress 
  1084.           );
  1085.  
  1086.    answer = SanityCheck( msg );
  1087.  
  1088.    if (answer >= 0)
  1089.       {
  1090.       struct Task *taddr = (struct Task *) TaskAddress;
  1091.       struct Node *tnode = &(taddr->tc_Node);
  1092.  
  1093.       ULONG OldPri = tnode->ln_Pri;
  1094.  
  1095.       // re-prioritize the task:
  1096.  
  1097.       if (ChangePriorityHandler( tnode->ln_Name,
  1098.                                  tnode->ln_Type,
  1099.                                  OldPri 
  1100.                                ) < 0)
  1101.          {
  1102.          // Error condition:
  1103.          }
  1104.       }
  1105.  
  1106.    return( (int) TRUE );
  1107. }
  1108.  
  1109. PRIVATE int FreezeClicked( int dummy )
  1110. {
  1111.    char  m[80], *msg = &m[0];
  1112.    int   answer = -1;
  1113.    
  1114.    sprintf( msg, "Are you SURE you want to Freeze %08x?", TaskAddress );
  1115.  
  1116.    answer = SanityCheck( msg );
  1117.  
  1118.    if (answer >= 0)
  1119.       {
  1120.       // Send the freeze command:
  1121.       }
  1122.  
  1123.    return( (int) TRUE );
  1124. }
  1125.  
  1126. PRIVATE int MoreClicked( int dummy )
  1127. {
  1128.    if (((struct Task *) TaskAddress)->tc_Node.ln_Type == NT_PROCESS)
  1129.       (void) HandleWindowInfo( (void *) TaskAddress, 3 );
  1130.    else
  1131.       (void) HandleWindowInfo( (void *) TaskAddress, 2 );
  1132.  
  1133.    SetWindowTitles( Wnd, WTitle, (UBYTE *) 0xFFFFFFFF );   
  1134.  
  1135.    return( (int) TRUE );
  1136. }
  1137.  
  1138. PRIVATE int SignalClicked( int dummy )
  1139. {
  1140. //   ULONG usersignals = 0L;
  1141.    char  m[80], *msg = &m[0];
  1142.    int   answer = -1;
  1143.    
  1144.    sprintf( msg, "Are you SURE you want to Signal %08x?", TaskAddress );
  1145.  
  1146.    answer = SanityCheck( msg );
  1147.  
  1148.    if (answer >= 0)
  1149.       {
  1150.       // get the signal number from the user via requester:
  1151. //      usersignals = GetUserSignals( (struct Task *) TaskAddress );
  1152. //      Signal( TaskAddress, usersignals );
  1153.       }
  1154.  
  1155.    return( (int) TRUE );
  1156. }
  1157.  
  1158. PRIVATE int BreakClicked( int dummy )
  1159. {
  1160.    char m[80], *msg = &m[0];
  1161.    int  answer = -1;
  1162.    
  1163.    sprintf( msg, "Are you SURE you want to Break %08x?", TaskAddress );
  1164.  
  1165.    answer = SanityCheck( msg );
  1166.  
  1167.    if (answer >= 0)
  1168.       {
  1169.       // Send the Break command:
  1170.       }
  1171.  
  1172.    return( (int) TRUE );
  1173. }
  1174.  
  1175. // CLose stuff: CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
  1176.  
  1177. PRIVATE void CloseTaskWindow( void )
  1178. {
  1179.    if (Wnd)
  1180.       {
  1181.       CloseWindow( Wnd );
  1182.       Wnd = NULL;
  1183.       }
  1184.  
  1185.    if (GList)
  1186.       {
  1187.       FreeGadgets( GList );
  1188.       GList = NULL;
  1189.       }
  1190.  
  1191.    if (TFont)
  1192.       {
  1193.       CloseFont( TFont );
  1194.       TFont = NULL;
  1195.       }
  1196.  
  1197.    return;
  1198. }
  1199.  
  1200. PRIVATE int TaskCloseWindow( void )
  1201. {
  1202.    CloseTaskWindow();
  1203.    return( (int) FALSE );
  1204. }
  1205.  
  1206. PRIVATE int CancelClicked( int dummy )
  1207. {
  1208.    return( TaskCloseWindow() );
  1209. }
  1210.  
  1211. // CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
  1212.  
  1213. PRIVATE int OpenTaskWindow( void )
  1214. {
  1215.    struct NewGadget  ng = { 0, };
  1216.    struct Gadget    *g  = NULL;
  1217.    UWORD             lc = 0, tc = 0;
  1218.    UWORD             wleft = WLeft, wtop = WTop, ww, wh;
  1219.  
  1220.    ComputeFont( Scr, Font, &CFont, WWidth, WHeight );
  1221.  
  1222.    ww = ComputeX( CFont.FontX, WWidth );
  1223.    wh = ComputeY( CFont.FontY, WHeight );
  1224.  
  1225.    if ((wleft + ww + CFont.OffX + Scr->WBorRight) > Scr->Width)
  1226.       wleft = Scr->Width - ww;
  1227.  
  1228.    if ((wtop + wh + CFont.OffY + Scr->WBorBottom) > Scr->Height)
  1229.       wtop = Scr->Height - wh;
  1230.  
  1231.    if ((TFont = OpenDiskFont( Font )) == NULL)
  1232.       return( -5 );
  1233.  
  1234.    if ((g = CreateContext( &GList )) == NULL)
  1235.       return( -1 );
  1236.  
  1237.    for (lc = 0, tc = 0; lc < T_CNT; lc++)
  1238.       {
  1239.       CopyMem( (char *) &TaskNGad[ lc ], (char *) &ng, 
  1240.                (long) sizeof( struct NewGadget )
  1241.              );
  1242.  
  1243.       ng.ng_VisualInfo = VisualInfo;
  1244.       ng.ng_TextAttr   = Font;
  1245.       ng.ng_LeftEdge   = CFont.OffX + ComputeX( CFont.FontX,
  1246.                                                 ng.ng_LeftEdge
  1247.                                               );
  1248.  
  1249.       ng.ng_TopEdge    = CFont.OffY + ComputeY( CFont.FontY,
  1250.                                                 ng.ng_TopEdge
  1251.                                               );
  1252.  
  1253.       ng.ng_Width      = ComputeX( CFont.FontX, ng.ng_Width );
  1254.       ng.ng_Height     = ComputeY( CFont.FontY, ng.ng_Height );
  1255.  
  1256.       TaskGadgets[ lc] = 
  1257.                     g  = CreateGadgetA( (ULONG) TaskGTypes[ lc ], 
  1258.                            g, 
  1259.                            &ng, 
  1260.                            (struct TagItem *) &TaskGTags[ tc ] );
  1261.  
  1262.       while (TaskGTags[tc])
  1263.          tc += 2;
  1264.  
  1265.       tc++;
  1266.  
  1267.       if (g == NULL)
  1268.          return( -2 );
  1269.       }
  1270.  
  1271.    if ( !(Wnd = OpenWindowTags( NULL,
  1272.                          
  1273.                   WA_Left,        wleft,
  1274.                   WA_Top,         wtop,
  1275.                   WA_Width,       ww + CFont.OffX + Scr->WBorRight,
  1276.                   WA_Height,      wh + CFont.OffY + Scr->WBorBottom,
  1277.  
  1278.                   WA_IDCMP,       LISTVIEWIDCMP | BUTTONIDCMP 
  1279.                     | IDCMP_CLOSEWINDOW | IDCMP_REFRESHWINDOW,
  1280.  
  1281.                   WA_Flags,       WFLG_DRAGBAR | WFLG_DEPTHGADGET 
  1282.                     | WFLG_CLOSEGADGET | WFLG_SMART_REFRESH 
  1283.                     | WFLG_ACTIVATE | WFLG_RMBTRAP,
  1284.                   
  1285.                   WA_Gadgets,     GList,
  1286.                   WA_Title,       WTitle,
  1287.                   TAG_DONE ))
  1288.       )
  1289.       return( -4 );
  1290.  
  1291.    GT_RefreshWindow( Wnd, NULL );
  1292.  
  1293.    return( 0 );
  1294. }
  1295.  
  1296. PRIVATE int HandleTaskIDCMP( void )
  1297. {
  1298.    struct IntuiMessage *m;
  1299.    int                 (*func)( int );
  1300.    BOOL                running = TRUE;
  1301.  
  1302.    while (running == TRUE)
  1303.       {
  1304.       if ((m = GT_GetIMsg( Wnd->UserPort )) == NULL)
  1305.          {
  1306.          (void) Wait( 1L << Wnd->UserPort->mp_SigBit );
  1307.          continue;
  1308.          }
  1309.  
  1310.       CopyMem( (char *) m, (char *) &IMsg, 
  1311.                (long) sizeof( struct IntuiMessage )
  1312.              );
  1313.  
  1314.       GT_ReplyIMsg( m );
  1315.  
  1316.       switch (IMsg.Class)
  1317.          {
  1318.          case IDCMP_REFRESHWINDOW:
  1319.             GT_BeginRefresh( Wnd );
  1320.             GT_EndRefresh( Wnd, TRUE );
  1321.             break;
  1322.  
  1323.          case IDCMP_CLOSEWINDOW:
  1324.             running = TaskCloseWindow();
  1325.             break;
  1326.  
  1327.          case IDCMP_GADGETUP:
  1328.          case IDCMP_GADGETDOWN:
  1329.             func    = (void *) ((struct Gadget *) IMsg.IAddress)->UserData;
  1330.             running = func( IMsg.Code );
  1331.             break;
  1332.          }
  1333.       }
  1334.  
  1335.    return( running );
  1336. }
  1337.  
  1338. PUBLIC int HandleTaskListView( void )
  1339. {
  1340.    int i = 0;
  1341.    
  1342.    TskLVNode.ln_Succ = (struct Node *) TskLVList.mlh_Tail;
  1343.    TskLVNode.ln_Pred = (struct Node *) TskLVList.mlh_Head;
  1344.    TskLVNode.ln_Type = 0;
  1345.    TskLVNode.ln_Pri  = 100;
  1346.    TskLVNode.ln_Name = "Address    Pri  Stack Signals  State     Type    Name";
  1347.  
  1348.    TskLVNodes[0] = TskLVNode;
  1349.  
  1350.    if (SetupSystemList( &OpenTaskWindow ) < 0)
  1351.       {
  1352.       fprintf( stderr, "Couldn't open a System ListViewer!\n" );
  1353.       return( -1 );
  1354.       }
  1355.    
  1356.    SetNotifyWindow( Wnd );
  1357.  
  1358.    for (i = 1; i <= MAXNODE; i++)
  1359.       {
  1360.       TskLVNodes[i].ln_Name = &NodeStrs[ i * 80 ];
  1361.       TskLVNodes[i].ln_Pri  = MAXNODE - i;
  1362.       }
  1363.  
  1364.    NewList( (struct List *) &TskLVList );      
  1365.  
  1366.    for (i = 0; i < MAXNODE; i++)
  1367.       Enqueue( (struct List *) &TskLVList, &TskLVNodes[ i ] );
  1368.  
  1369.    // Make the list:
  1370.    (void) MakeTaskList();   
  1371.  
  1372.    ModifyListView( TaskGadgets[ TaskLV ], Wnd, 
  1373.                    (struct List *) &TskLVList, NULL
  1374.                  );
  1375.  
  1376.    GT_RefreshWindow( Wnd, NULL );
  1377.  
  1378.    (void) HandleTaskIDCMP();
  1379.    
  1380.    ShutdownSystemList();
  1381.    return( 0 );
  1382. }
  1383.  
  1384. PUBLIC int main( void )
  1385. {
  1386.    return( HandleTaskListView() );
  1387. }
  1388.  
  1389. /* ------------------- END of SysTasks.c file! --------------------- */
  1390.